#pragma once
#include "common.hpp"
#include "inet_addr.hpp"

using namespace logger_module;
#define default_listensk 0
class tcp_server
{
public:
    tcp_server(const uint16_t& port)
    :_port(port),
    _listen_socket(default_listensk),
    _isrunning(false){}
    void service(int sockfd,InetAddr peer)
    {
        char buffer[1024];
        while (true)
        {
        ssize_t read_num = read(sockfd,buffer,sizeof(buffer)-1);
        if(read_num>0)
        {
            buffer[read_num]=0;
            std::cout<<peer.addr_name()<<"say#"<<buffer<<std::endl;
            std::string echo_string =buffer;
            write(sockfd,echo_string.c_str(),echo_string.size());

        }
        if(read_num==0)
        {
            LOG(log_level::INFO)<<"he is quit: "<<peer.addr_name();
            close(sockfd);
            break;
        }
        if(read_num<0)
        {
            LOG(log_level::FATAL)<<"recive nothing "<<peer.addr_name();
            close(sockfd);
            break;
        }
        }
    }
    void Init()
    {
        InetAddr local(_port);
        _listen_socket=socket(AF_INET,SOCK_STREAM,0);
        if(_listen_socket<0)
        {
            LOG(log_level::FATAL)<<"get socket fail";
            exit(GET_SOCKET_ERR);
        }
        LOG(log_level::INFO)<<"get socket success:"<<_listen_socket;
        int bind_ret=bind(_listen_socket,TO_SOCKADDR(local.Addr()),sizeof(local.Addr()));
        if(bind_ret!=0)
        {
            LOG(log_level::FATAL)<<"bind fail";
            exit(BIND_ERR);
        }
        LOG(log_level::INFO)<<"bind success";
        int listen_ret=listen(_listen_socket,8);
        if(listen_ret!=0)
        {
            LOG(log_level::FATAL)<<"listen fail";
            exit(LISTEN_ERR);
        }
        LOG(log_level::INFO)<<"listen success: "<<_listen_socket;
    }
    void Run()
    {
        _isrunning=true;
        while(_isrunning)
        {
            InetAddr peer;
            unsigned int peerA_len=sizeof(peer.Addr());
            int sockfd = accept(_listen_socket,TO_SOCKADDR(peer.Addr()),&peerA_len);
            if(sockfd<0)
            {
                LOG(log_level::ERROR)<<"accept fail";
            }
            LOG(log_level::INFO)<<"accept success: "<<peer.addr_name();
            service(sockfd,peer);
        }
        LOG(log_level::FATAL)<<"server stop";
        _isrunning=false;
    }
    int _listen_socket;
    uint16_t _port;
    bool _isrunning;

};